package com.estar.integaration.Helper;

import com.estar.integaration.Service.*;
import com.estar.integaration.Util.MaterialUtil;
import com.estar.integaration.Util.StringUtil;
import com.estar.integaration.Util.Util;
import com.estar.integaration.entity.*;
import com.estar.integaration.entity.NoSQL.Res;
import com.google.gson.Gson;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * Author: YJL
 * Date: 2021/11/22 13:27
 **/

@Component
@NoArgsConstructor
public class MaterialCalcHelper {

  @Autowired
  IMaterialService bridgeMaterialService;
  private static IMaterialService materialService;

  @Autowired
  IAcodeProductVoService bridgeAcodeProductVoService;
  private static IAcodeProductVoService acodeProductVoService;


  @Autowired
  IChildAcodeService bridgeChildAcodeService;
  private static IChildAcodeService childAcodeService;

  @Autowired
  IMaterialVoService bridgeMaterialVoService;
  private static IMaterialVoService materialVoService;

  @Autowired
  IProductDbService bridgeProductDbService;
  private static IProductDbService productDbService;

  public MaterialCalcHelper(IMaterialService materialService,IAcodeProductVoService acodeProductVoService) {
    this.materialService = materialService;
    this.acodeProductVoService = acodeProductVoService;
  }


  public static class TechType{
    public static final String buy = "外购件清单";//外购件
    public static final String buyChange = "外购件变更清单";//外购件变更
    public static final String parts = "外购件配件清单";//配件
    public static final String electrical = "电气清单";//电气
    public static final String afterBuy = "外购件售后清单";//售后
  }


  /**
   * 根据不同的产品类型类型计算数值
   * @return
   */
  public static Res insertwithCalc(ProductMachineInfo productMachineInfo,HashMap<String,Date> scheduleHash,Boolean isUrgent) {
    //完整A码,产品id 暂时无交期
    AcodeProductVo acodeProductVo = new AcodeProductVo(Util.getUUID(),productMachineInfo.getProductDb().getACode(),productMachineInfo.getProductDb().getId(),null);
    String Acode = productMachineInfo.getProductDb().getACode();
    //增补一定得是有productDb(AcodeProductVo)的
    AcodeProductVo oldAcodeProductVo = acodeProductVoService.selectByfullAcode(Acode);
    switch (productMachineInfo.getProductDb().getProductType().replaceAll(" ","")){
      case TechType.buy:
      case TechType.parts:
      case TechType.electrical:
        return justInsert(productMachineInfo, scheduleHash, isUrgent, acodeProductVo);
      case TechType.buyChange://变更
        //若没有productDb
        if(oldAcodeProductVo == null){
          return justInsert(productMachineInfo, scheduleHash, isUrgent, acodeProductVo);
        }
        return insert_change(productMachineInfo,isUrgent);
      case TechType.afterBuy://售后
        //若没有productDb
        if(oldAcodeProductVo == null){
          return justInsert(productMachineInfo, scheduleHash, isUrgent, acodeProductVo);
        }
        return insert_afterBuy(productMachineInfo,isUrgent);
    }
//    return new Res("40000","清单类型填写错误");
    return Res.fail("40000","清单类型填写错误");
  }


  /**
   * 根据不同的产品类型删除一个文档的各种物料
   * @return
   */
  public static Res deletewithCalc(ProductMachineInfo productMachineInfo) {
    switch (productMachineInfo.getProductDb().getProductType().replaceAll(" ","")){
      case TechType.buy://外购件
      case TechType.parts://配件
      case TechType.electrical://电气
      case TechType.afterBuy://售后
        return justDelete(productMachineInfo);
      case TechType.buyChange://变更
        return deleteFromPlusorMinus(productMachineInfo);
    }
    return new Res("40000","清单类型填写错误");
  }

  /**
   * 仅找A码添加进去
   * @param
   */
  private static Res justInsert(ProductMachineInfo productMachineInfo,HashMap<String,Date> scheduleHash,Boolean isUrgent,AcodeProductVo acodeProductVo){
    //解析出childAcode并写入数据库
    List<ChildAcode> childAcodeList = MaterialUtil.parseSomeAcode_WriteinSQL(productMachineInfo,childAcodeService,acodeProductVo.getId());
    //错误
    if(productMachineInfo == null){
      return new Res("40001","错误");
    }
    //同张表内容合并以及紧急
    productMachineInfo.setMaterialVOList(MaterialUtil.setIsUrgentandProductId(MaterialUtil.mergeOneExecelSameMaterial(productMachineInfo.getMaterialVOList()),isUrgent,productMachineInfo.getProductDb()));
    //交期
    Date delivery = null;
    for(ChildAcode childAcode : childAcodeList){
      //完整A码中的其中一个子找到交期
      if(scheduleHash.containsKey(childAcode.getACode())){
        delivery = scheduleHash.get(childAcode.getACode());
        //设置交期
        acodeProductVo.setDelivery(delivery);
        //写入SQL
        acodeProductVoService.insert(acodeProductVo);
        //本产品的所有物料都找到了交期
        List<Material> materialList  = MaterialUtil.parseMaterialVOList2Material(productMachineInfo.getMaterialVOList(),delivery,acodeProductVo);
        /**完成所有的material的解析，形成有物料的material**/
        //设置product的交期
        productMachineInfo.getProductDb().setProductDeliveryTime(delivery);
        materialService.saveBatch(materialList);
        productDbService.insert(productMachineInfo.getProductDb());
        return new Res("20000",new Gson().toJson(materialList));
      }
    }
    //未找到交期
    if(delivery == null){
      List<MaterialVo> materialVoList = productMachineInfo.getMaterialVOList();
      //写入数据库
      materialVoService.saveBatch(materialVoList);
      productDbService.insert(productMachineInfo.getProductDb());
      //未找到交期
      return new Res("20000",new Gson().toJson(materialVoList));
    }
    return null;
  }

  /**
   * 表里有的，数字变动，合并上去,变更
   * @param
   */
  private static Res insert_change(ProductMachineInfo productMachineInfo,Boolean isUrgent){

    String Acode = productMachineInfo.getProductDb().getACode();
    //增补一定得是有productDb的
    AcodeProductVo acodeProductVo = acodeProductVoService.selectByfullAcode(Acode);

    String productId = acodeProductVo.getProductId();
    //SQL内本A码的所有物料
    List<Material> materialList = materialService.selectListByproductId(productId);
    //形成本product中所有物料的Hash，<物料号,物料>
    HashMap<String,Material> materialNoMaHash = MaterialUtil.getMaterialNoMaterialHashByList(materialList);
    //新文件来的物料List
    List<MaterialVo> materialVoList = productMachineInfo.getMaterialVOList();
    //用来更新的临时List 用来删除的临时List
    List<Material> updateBatchList = new ArrayList<>();List<Material> insertBatchList = new ArrayList<>();

    for(MaterialVo mVO : materialVoList){
      if(materialNoMaHash.containsKey(mVO.getMaterialNo())){
        //取出
        Material material = materialNoMaHash.get(mVO.getMaterialNo());
        material.setIsUrgent(isUrgent);
        if(mVO.getPrice().equals("+") || mVO.getPrice().equals("﹢")){
          //设置新值
          material.setPlanQuantity(material.getPlanQuantity() + mVO.getPlanQuantity());
          material.setUnpurchased(material.getUnpurchased() + mVO.getPlanQuantity());
        }else if(mVO.getPrice().equals("-")){
          //设置新值
          material.setPlanQuantity(material.getPlanQuantity() - mVO.getPlanQuantity());
          material.setUnpurchased(material.getUnpurchased() - mVO.getPlanQuantity());
        }
        //加入
        updateBatchList.add(material);

      }else {
        mVO.setIsUrgent(isUrgent);
        mVO.setDelivery(acodeProductVo.getDelivery());
        mVO.setFullACodeId(acodeProductVo.getId());
        mVO.setProductId(acodeProductVo.getProductId());
        Material material = Material.cloneMVO2M(mVO);
        if(mVO.getPrice().equals("+")){
          material.setUnpurchased(mVO.getPlanQuantity());
          material.setPurchased(0d);
        }else {
          material.setPlanQuantity(0 - mVO.getPlanQuantity());
          material.setUnpurchased(0 - mVO.getPlanQuantity());
          material.setPurchased(0d);
        }
        insertBatchList.add(material);
      }
    }

    materialService.updateBatchById(updateBatchList);
    materialService.saveBatch(insertBatchList);
    return new Res("20000",new Gson().toJson(materialVoList));

  }

  /**
   * 表里有的，数字变动，合并上去,变更
   * @param
   */
  private static Res insert_afterBuy(ProductMachineInfo productMachineInfo,Boolean isUrgent){

    //售后一定得是有A码的
    String Acode = productMachineInfo.getProductDb().getACode();

    AcodeProductVo acodeProductVo = acodeProductVoService.selectByfullAcode(Acode);

    String productId = acodeProductVo.getProductId();
    //SQL内本A码的所有物料
    List<Material> materialList = materialService.selectListByproductId(productId);
    //形成本product中所有物料的Hash，<物料号,物料>
    HashMap<String,Material> materialNoMaHash = MaterialUtil.getMaterialNoMaterialHashByList(materialList);
    //新文件来的List
    List<MaterialVo> materialVoList = productMachineInfo.getMaterialVOList();
    //用来更新的临时List 用来删除的临时List
    List<Material> updateBatchList = new ArrayList<>();List<Material> insertBatchList = new ArrayList<>();

    for(MaterialVo mVO : materialVoList){

      if(materialNoMaHash.containsKey(mVO.getMaterialNo())){
        //取出
        Material material = materialNoMaHash.get(mVO.getMaterialNo());

        material.setIsUrgent(isUrgent);
        //设置新值
        material.setPlanQuantity(material.getPlanQuantity() + mVO.getPlanQuantity());

        material.setUnpurchased(material.getUnpurchased() + mVO.getPlanQuantity());
        //加入
        updateBatchList.add(material);
      }else {

        mVO.setIsUrgent(isUrgent);
        mVO.setFullACodeId(acodeProductVo.getId());
        mVO.setProductId(acodeProductVo.getProductId());
        mVO.setDelivery(acodeProductVo.getDelivery());
        Material material = Material.cloneMVO2M(mVO);
        material.setUnpurchased(mVO.getPlanQuantity());
        material.setPurchased(0d);
        material.setInventory(0d);
        insertBatchList.add(material);
      }
    }
    materialService.updateBatchById(updateBatchList);
    materialService.saveBatch(insertBatchList);
    return new Res("20000",new Gson().toJson(materialVoList));
  }

  /**
   * 删除历史文件后执行仅删除(不是变更则直接删掉)
   * @param productMachineInfo
   */
  private static Res justDelete(ProductMachineInfo productMachineInfo){
    List<MaterialVo> materialVoList = productMachineInfo.getMaterialVOList();
    HashMap<String,MaterialVo> materialVoHashMap = new HashMap<>();
    materialVoList.forEach(mVO -> materialVoHashMap.put(mVO.getMaterialNo(),mVO));
    List<Material> materialList = materialService.selectListByProductACode(productMachineInfo.getProductDb().getACode());//拿到此A码的所有物料
    //循环所有本机台号的物料，如果有对上号需要删的则删除掉
    for(Material m : materialList){
      if(materialVoHashMap.containsKey(m.getMaterialNo())){//里头有需要删的,直接去掉
        Double needDeleteQuantity = materialVoHashMap.get(m.getMaterialNo()).getPlanQuantity();
        //BOM和需购减掉
        m.setPlanQuantity(m.getPlanQuantity() - needDeleteQuantity);
        m.setUnpurchased(m.getUnpurchased() - needDeleteQuantity);
      }
    }
    //更新物料表
    materialService.updateBatchById(materialList);
    return new Res("20000","删除成功");
  }
  /**
   * 删除历史文件后执行变更的删除(不是变更则直接删掉)
   * 反向操作，如果是加则扣掉，如果是减则加上
   * @param productMachineInfo
   */
  private static Res deleteFromPlusorMinus(ProductMachineInfo productMachineInfo){
    List<MaterialVo> materialVoList = productMachineInfo.getMaterialVOList();
    HashMap<String,MaterialVo> materialVoHashMap = new HashMap<>();
    materialVoList.forEach(mVO -> materialVoHashMap.put(mVO.getMaterialNo(),mVO));
    List<Material> materialList = materialService.selectListByProductACode(productMachineInfo.getProductDb().getACode());//拿到此A码的所有物料

    //循环所有本机台号的物料，如果有对上号需要删的则删除掉
    for(Material m : materialList){
      if(materialVoHashMap.containsKey(m.getMaterialNo())){//里头有需要删的,直接去掉
        MaterialVo materialVo = materialVoHashMap.get(m.getMaterialNo());
        Double needDeleteQuantity = materialVoHashMap.get(m.getMaterialNo()).getPlanQuantity();
        if(materialVo.getPrice().equals("+") || materialVo.getPrice().equals("﹢") ){
          m.setPlanQuantity(m.getPlanQuantity() - needDeleteQuantity);
          m.setUnpurchased(m.getUnpurchased() - needDeleteQuantity);
        }else {
          m.setPlanQuantity(m.getPlanQuantity() + needDeleteQuantity);//反向操作
          m.setUnpurchased(m.getUnpurchased() + needDeleteQuantity);
        }
      }
    }
    //更新物料表
    materialService.updateBatchById(materialList);
    return new Res("20000","删除成功");
  }

  @PostConstruct
  public void init(){
    //注入对象
    materialVoService = bridgeMaterialVoService;
    acodeProductVoService = bridgeAcodeProductVoService;

    childAcodeService = bridgeChildAcodeService;

    materialService = bridgeMaterialService;

    productDbService = bridgeProductDbService;

  }








}
